using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine; // 添加Unity引擎引用

namespace MermaidParser
{
    /// <summary>
    /// 定义 Mermaid 流程图中所支持的节点形状类型。
    /// 每种类型对应 Mermaid 语法中的特定节点表示法。
    /// </summary>
    public enum NodeShape
    {
        /// <summary>
        /// 矩形节点。默认节点形状，用于表示常规步骤或操作。
        /// Mermaid 语法: `节点ID[节点文本]`
        /// 示例: `A[开始]`
        /// </summary>
        Rect,

        /// <summary>
        /// 圆形节点。通常用于表示图的开始和结束节点。
        /// Mermaid 语法: `节点ID((节点文本))`
        /// 示例: `End((结束))`
        /// </summary>
        Circle,

        /// <summary>
        /// 圆角矩形节点。用途与矩形类似，但视觉效果更柔和。
        /// Mermaid 语法: `节点ID(节点文本)`
        /// 示例: `Process(数据处理)`
        /// </summary>
        RoundRect,

        /// <summary>
        /// 菱形节点。用于表示判断、决策或条件分支点。
        /// Mermaid 语法: `节点ID{节点文本}`
        /// 示例: `Decision{是否继续?}`
        /// </summary>
        Rhombus,

        /// <summary>
        /// 跑道形节点。也称为"stadium"形状，常用于表示特定流程，如数据库操作或预处理。
        /// Mermaid 语法: `节点ID([节点文本])`
        /// 示例: `Input([用户输入])`
        /// </summary>
        Stadium,

        /// <summary>
        /// 子程序形状节点。用于表示一个子流程或可复用的模块。
        /// Mermaid 语法: `节点ID[[节点文本]]`
        /// 示例: `Subroutine[[计算模块]]`
        /// </summary>
        Subroutine,

        /// <summary>
        /// 圆柱形节点。通常用于表示数据库或数据存储。
        /// Mermaid 语法: `节点ID[(节点文本)]`
        /// 示例: `Database[(MySQL数据库)]`
        /// </summary>
        Cylinder,

        /// <summary>
        /// 六边形节点。用于表示预处理或准备步骤。
        /// Mermaid 语法: `节点ID{{节点文本}}`
        /// 示例: `Preprocess{{数据清洗}}`
        /// </summary>
        Hexagon,

        /// <summary>
        /// 平行四边形节点（右倾）。用于表示输入/输出操作。
        /// Mermaid 语法: `节点ID[/节点文本/]`
        /// 示例: `Input[/用户输入/]`
        /// </summary>
        ParallelogramRight,

        /// <summary>
        /// 平行四边形节点（左倾）。用于表示输入/输出操作。
        /// Mermaid 语法: `节点ID[\节点文本\]`
        /// 示例: `Output[\处理结果\]`
        /// </summary>
        ParallelogramLeft,

        /// <summary>
        /// 双圈圆形节点。用于强调特定节点或表示特殊状态。
        /// Mermaid 语法: `节点ID(((节点文本)))`
        /// 示例: `Important(((关键步骤)))`
        /// </summary>
        DoubleCircle,

        /// <summary>
        /// 非对称形状节点。用于表示与其他节点不同的特殊操作。
        /// Mermaid 语法: `节点ID>节点文本]`
        /// 示例: `Manual>手动处理]`
        /// </summary>
        Asymmetric,

        /// <summary>
        /// 梯形节点（上宽下窄）。用于表示手动操作或特定处理。
        /// Mermaid 语法: `节点ID[/节点文本\]`
        /// 示例: `Trapezoid[/处理数据\]`
        /// </summary>
        Trapezoid,

        /// <summary>
        /// 倒梯形节点（上窄下宽）。用于表示手动操作或特定处理。
        /// Mermaid 语法: `节点ID[\节点文本/]`
        /// 示例: `InvertedTrapezoid[\处理数据/]`
        /// </summary>
        InvertedTrapezoid,

        /// <summary>
        /// 圆形矩形节点。矩形与圆形的结合，用于表示特殊类型的操作。
        /// Mermaid 语法: `节点ID(节点文本)`
        /// 与 RoundRect 语法相同，但视觉表现不同
        /// 示例: `Special(特殊处理)`
        /// </summary>
        CircleRect
    }

    // 连线类型
    public enum LinkType
    {
        Solid,
        Dotted,
        Bold,
        Open
    }

    // 箭头类型
    public enum ArrowType
    {
        None,
        Arrow,
        Circle,
        Cross
    }

    // 节点类
    public class Node
    {
        public string Id { get; set; }
        public string Text { get; set; }
        public NodeShape Shape { get; set; }

        public Node(string id, string text, NodeShape shape = NodeShape.Rect)
        {
            Id = id;
            Text = text;
            Shape = shape;
        }

        public override string ToString()
        {
            return $"{Id}: {Text} ({Shape})";
        }
    }

    // 连线类
    public class Link
    {
        public string FromNodeId { get; set; }
        public string ToNodeId { get; set; }
        public string Text { get; set; }
        public LinkType LineType { get; set; }
        public ArrowType StartArrow { get; set; }
        public ArrowType EndArrow { get; set; }

        public Link(string from, string to, string text = "",
                   LinkType lineType = LinkType.Solid,
                   ArrowType startArrow = ArrowType.None,
                   ArrowType endArrow = ArrowType.Arrow)
        {
            FromNodeId = from;
            ToNodeId = to;
            Text = text;
            LineType = lineType;
            StartArrow = startArrow;
            EndArrow = endArrow;
        }

        public override string ToString()
        {
            return $"{FromNodeId} -> {ToNodeId}: {Text} ({LineType})";
        }
    }

    // 子图类
    public class SubGraph
    {
        public string Id { get; set; }
        public string Title { get; set; }
        public List<Node> Nodes { get; set; }
        public List<Link> Links { get; set; }
        public List<SubGraph> SubGraphs { get; set; }

        public SubGraph(string id, string title)
        {
            Id = id;
            Title = title;
            Nodes = new List<Node>();
            Links = new List<Link>();
            SubGraphs = new List<SubGraph>();
        }

        public override string ToString()
        {
            return $"{Id}: {Title}";
        }
    }

    // 流程图类
    public class Flowchart
    {
        public string Direction { get; set; }
        public List<Node> Nodes { get; set; }
        public List<Link> Links { get; set; }
        public List<SubGraph> SubGraphs { get; set; }

        public Flowchart()
        {
            Nodes = new List<Node>();
            Links = new List<Link>();
            SubGraphs = new List<SubGraph>();
        }
    }

    // Mermaid解析器
    public class MermaidParser
    {
        private Flowchart flowchart;
        private SubGraph currentSubGraph;
        private Stack<SubGraph> subGraphStack;

        public MermaidParser()
        {
            flowchart = new Flowchart();
            subGraphStack = new Stack<SubGraph>();
        }

        public Flowchart Parse(string mermaidCode)
        {
            string[] lines = mermaidCode.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string line in lines)
            {
                string trimmedLine = line.Trim();

                if (string.IsNullOrEmpty(trimmedLine)) continue;

                // 检查流程图方向
                if (trimmedLine.StartsWith("graph"))
                {
                    ParseDirection(trimmedLine);
                }
                // 检查子图开始
                else if (trimmedLine.StartsWith("subgraph"))
                {
                    ParseSubgraphStart(trimmedLine);
                }
                // 检查子图结束
                else if (trimmedLine == "end")
                {
                    ParseSubgraphEnd();
                }
                else
                {
                    // 处理普通行（可能包含连线和节点）
                    ParseLine(trimmedLine);
                }
            }

            return flowchart;
        }

        private void ParseDirection(string line)
        {
            // 提取方向：TD, TB, BT, LR, RL
            var match = Regex.Match(line, @"graph\s+(\w+)");
            if (match.Success)
            {
                flowchart.Direction = match.Groups[1].Value;
            }
        }

        private void ParseSubgraphStart(string line)
        {
            // 提取子图ID和标题
            var match = Regex.Match(line, @"subgraph\s+([\w_]+)\s*(?:\[(.*?)\])?");
            if (match.Success)
            {
                string id = match.Groups[1].Value;
                string title = match.Groups[2].Success ? match.Groups[2].Value : id;

                var subGraph = new SubGraph(id, title);

                if (currentSubGraph != null)
                {
                    currentSubGraph.SubGraphs.Add(subGraph);
                    subGraphStack.Push(currentSubGraph);
                }
                else
                {
                    flowchart.SubGraphs.Add(subGraph);
                }

                currentSubGraph = subGraph;
            }
        }

        private void ParseSubgraphEnd()
        {
            if (subGraphStack.Count > 0)
            {
                currentSubGraph = subGraphStack.Pop();
            }
            else
            {
                currentSubGraph = null;
            }
        }

        private void ParseLine(string line)
        {
            // 先处理节点定义
            string remainingLine = ExtractNodesFromLine(line);

            // 再处理连线
            ExtractLinksFromLine(remainingLine);
        }


        private string ExtractNodesFromLine(string line)
        {
            string remainingLine = line;

            // 定义节点模式及其对应的形状
            var nodePatterns = new List<Tuple<string, NodeShape>>
    {
        // A{text} - 菱形节点
        new(@"([\w_]+)\{(.*?)\}", NodeShape.Rhombus),
        // A((text)) - 圆形节点
        new(@"([\w_]+)\(\((.*?)\)\)", NodeShape.Circle),
        // A[[text]] - 子程序节点
        new(@"([\w_]+)\[\[(.*?)\]\]", NodeShape.Subroutine),
        // A[text] - 矩形节点
        new(@"([\w_]+)\[(.*?)\]", NodeShape.Rect),
        // A(text) - 圆角矩形节点
        new(@"([\w_]+)\((.*?)\)", NodeShape.RoundRect)
    };

            bool foundNode;

            do
            {
                foundNode = false;

                foreach (var patternTuple in nodePatterns)
                {
                    var pattern = patternTuple.Item1;
                    var shape = patternTuple.Item2;

                    var match = Regex.Match(remainingLine, pattern);
                    if (match.Success)
                    {
                        foundNode = true;

                        string id = match.Groups[1].Value;
                        string text = match.Groups[2].Value;

                        // 去除文本前后的双引号（如果存在）
                        text = RemoveQuotes(text);

                        // 创建节点，直接使用模式对应的形状
                        var node = new Node(id, text, shape);

                        if (currentSubGraph != null)
                        {
                            currentSubGraph.Nodes.Add(node);
                        }
                        else
                        {
                            flowchart.Nodes.Add(node);
                        }

                        // 从行中移除已处理的节点，替换为节点ID
                        remainingLine = remainingLine.Remove(match.Index, match.Length);
                        remainingLine = remainingLine.Insert(match.Index, id);

                        break; // 处理下一个匹配
                    }
                }
            } while (foundNode);

            return remainingLine;
        }

        // 辅助方法：去除文本前后的双引号
        private string RemoveQuotes(string text)
        {
            if (string.IsNullOrEmpty(text))
                return text;

            // 去除前后的双引号
            if (text.StartsWith("\"") && text.EndsWith("\""))
            {
                return text.Substring(1, text.Length - 2);
            }

            // 去除前后的单引号
            if (text.StartsWith("'") && text.EndsWith("'"))
            {
                return text.Substring(1, text.Length - 2);
            }

            return text;
        }
        private string ExtractNodesFromLine_(string line)
        {
            string remainingLine = line;

            // 定义节点模式及其对应的形状
            var nodePatterns = new List<Tuple<string, NodeShape>> // 这里有顺序依赖
    {
        // A{text} - 菱形节点
        new(@"([\w_]+)\{(.*?)\}", NodeShape.Rhombus),
        // A((text)) - 圆形节点
        new(@"([\w_]+)\(\((.*?)\)\)", NodeShape.Circle),
        // A[[text]] - 子程序节点 (添加这个模式)
        new(@"([\w_]+)\[\[(.*?)\]\]", NodeShape.Subroutine),
        // A[text] - 矩形节点
        new(@"([\w_]+)\[(.*?)\]", NodeShape.Rect),
        // A(text) - 圆角矩形节点
        new(@"([\w_]+)\((.*?)\)", NodeShape.RoundRect)
    };

            bool foundNode;

            do
            {
                foundNode = false;

                foreach (var patternTuple in nodePatterns)
                {
                    var pattern = patternTuple.Item1;
                    var shape = patternTuple.Item2;

                    var match = Regex.Match(remainingLine, pattern);
                    if (match.Success)
                    {
                        foundNode = true;

                        string id = match.Groups[1].Value;
                        string text = match.Groups[2].Value;

                        // 创建节点，直接使用模式对应的形状
                        var node = new Node(id, text, shape);

                        if (currentSubGraph != null)
                        {
                            currentSubGraph.Nodes.Add(node);
                        }
                        else
                        {
                            flowchart.Nodes.Add(node);
                        }

                        // 从行中移除已处理的节点，替换为节点ID
                        remainingLine = remainingLine.Remove(match.Index, match.Length);
                        remainingLine = remainingLine.Insert(match.Index, id);

                        break; // 处理下一个匹配
                    }
                }
            } while (foundNode);

            return remainingLine;
        }
        
        private void ExtractLinksFromLine(string line)
        {
            // 定义连线模式及其对应的类型和箭头
            var linkPatterns = new List<Tuple<string, LinkType, ArrowType, ArrowType, bool>>
            {
                // A --> B (实线箭头)
                new(
                    @"([\w_]+)\s*-->\s*([\w_]+)",
                    LinkType.Solid, ArrowType.None, ArrowType.Arrow, false),
        
                // A -->|text| B (实线带文本箭头)
                new(
                    @"([\w_]+)\s*-->\|(.*?)\|\s*([\w_]+)",
                    LinkType.Solid, ArrowType.None, ArrowType.Arrow, true),
        
                // A -- text --> B (实线带文本箭头)
                new(
                    @"([\w_]+)\s*--\s*(.*?)\s*-->\s*([\w_]+)",
                    LinkType.Solid, ArrowType.None, ArrowType.Arrow, true),
        
                // A -.- B (虚线箭头)
                new(
                    @"([\w_]+)\s*-\.-\s*([\w_]+)",
                    LinkType.Dotted, ArrowType.None, ArrowType.Arrow, false),
        
                // A -. text .- B (虚线带文本箭头)
                new(
                    @"([\w_]+)\s*-\.\s*(.*?)\s*\.-\s*([\w_]+)",
                    LinkType.Dotted, ArrowType.None, ArrowType.Arrow, true),
        
                // A ==> B (粗线箭头)
                new(
                    @"([\w_]+)\s*==>\s*([\w_]+)",
                    LinkType.Bold, ArrowType.None, ArrowType.Arrow, false),
        
                // A == text ==> B (粗线带文本箭头)
                new(
                    @"([\w_]+)\s*==\s*(.*?)\s*==>\s*([\w_]+)",
                    LinkType.Bold, ArrowType.None, ArrowType.Arrow, true)
            };

            string remainingLine = line;
            bool foundLink;

            do
            {
                foundLink = false;

                foreach (var patternTuple in linkPatterns)
                {
                    var pattern = patternTuple.Item1;
                    var linkType = patternTuple.Item2;
                    var startArrow = patternTuple.Item3;
                    var endArrow = patternTuple.Item4;
                    var hasText = patternTuple.Item5;

                    var match = Regex.Match(remainingLine, pattern);
                    if (match.Success)
                    {
                        foundLink = true;

                        string fromId = match.Groups[1].Value;
                        string toId;
                        string text = "";

                        // 根据是否有文本来提取信息
                        if (hasText)
                        {
                            text = match.Groups[2].Value.Trim();
                            toId = match.Groups[3].Value;
                        }
                        else
                        {
                            toId = match.Groups[2].Value;
                        }

                        // 创建连线，直接使用模式对应的属性
                        var link = new Link(fromId, toId, text, linkType, startArrow, endArrow);

                        if (currentSubGraph != null)
                        {
                            currentSubGraph.Links.Add(link);
                        }
                        else
                        {
                            flowchart.Links.Add(link);
                        }

                        // 从行中移除已处理的连线
                        remainingLine = remainingLine.Remove(match.Index, match.Length);
                        break; // 处理下一个匹配
                    }
                }
            } while (foundLink);
        }
    }

    // 使用示例
    public class MermaidExample
    {
        public static Flowchart Example(string mermaidCode = null)
        {
            mermaidCode ??= @"
graph TD
    A[开始] --> B{判断}
    B -->|是| C[选项1]
    B -->|否| D[选项2]
    
    subgraph 子图1 [子流程]
        C --> E[子步骤1]
        D --> F[子步骤2]
        E --> G[结束子流程]
        F --> G
    end
    
    G --> H[最终步骤]
    H --> I((结束))
";

            MermaidParser parser = new();
            Flowchart flowchart = parser.Parse(mermaidCode);

            // 使用Debug.Log输出结果
            Debug.Log($"流程图方向: {flowchart.Direction}");
            Debug.Log($"节点数量: {flowchart.Nodes.Count}");
            Debug.Log($"连线数量: {flowchart.Links.Count}");
            Debug.Log($"子图数量: {flowchart.SubGraphs.Count}");

            // 打印所有节点
            Debug.Log("\n节点列表:");
            foreach (var node in flowchart.Nodes)
            {
                Debug.Log($"  {node}");
            }

            // 打印所有连线
            Debug.Log("\n连线列表:");
            foreach (var link in flowchart.Links)
            {
                Debug.Log($"  {link}");
            }

            // 打印子图中的节点和连线
            if (flowchart.SubGraphs.Count > 0)
            {
                Debug.Log("\n子图内容:");
                foreach (var subGraph in flowchart.SubGraphs)
                {
                    Debug.Log($"子图: {subGraph.Id} - {subGraph.Title}");
                    foreach (var node in subGraph.Nodes)
                    {
                        Debug.Log($"  节点: {node}");
                    }
                    foreach (var link in subGraph.Links)
                    {
                        Debug.Log($"  连线: {link}");
                    }
                }
            }
            return flowchart;
        }
    }
}
/*
1. 基本节点形状
形状	    语法示例	说明	
矩形	    A[文本]	    默认节点，表示一般操作或步骤	
圆角矩形	B(文本)	    通常表示开始或结束节点	
菱形	    C{文本}	    表示判断或决策点	
圆形	    D((文本))	另一种开始/结束表示方式	
六边形	    E{{文本}}	表示预处理或准备	{{文本}}
平行四边形	F[/文本/] 或 F[\文本\]	表示输入/输出操作	
双圈圆形	G(((文本)))	表示子程序或子流程	

2. 节点标识符
每个节点需要一个唯一ID（如 A, B, start, end 等）
ID 后面跟着形状定义和显示文本：ID[显示文本]

二、连接线（Links/Edges）
1. 基本连接线类型
线型	        语法示例	    说明	
实线带箭头	    A --> B	        默认连接，表示流程方向	
实线无箭头	    A --- B	        表示关联，无方向性	
虚线带箭头	    A -.-> B	    表示可选或非主要流程	
虚线无箭头	    A -.- B	        表示弱关联	-.-
粗实线带箭头	A ==> B	        表示重要或主要流程	
粗实线无箭头	A === B	        表示强关联

2. 带标签的连接线
可以在连接线上添加文本标签：
    A -->|标签文本| B
    C -- 这也是标签 --- D
    E -. 虚线标签 .-> F

3. 连接线长度
可以通过添加更多-或.来延长连接线：

4. 多方向箭头
--o : 末端为圆形的箭头
--x : 末端为X的箭头

三、子图（Subgraphs）
用于将相关节点分组，提高流程图的可读性。
flowchart TB
    subgraph 子图名称[可选显示文本]
        A[节点A]
        B[节点B]
    end
    
    C[外部节点] --> A
    B --> D[另一个外部节点]

 */